﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace sdd.subsystems.config
{
    class DynConfigurator : IConfigurator
    {
        private const string CONFIGURATOR_TEMPLATE = "using System; using sirp;\npublic class Configurator {{\n\tpublic static void main(Director Director) {{\n{0}\n\t}}\n}}";
        
        public Director Director { set; get; }

        public bool LoadConfigurator(string fileName)
        {
            string data = ""; string code = "";
            string template = CONFIGURATOR_TEMPLATE;

            try
            {
                // load configurator code
                using (StreamReader sr = new StreamReader(fileName))
                {
                    data = sr.ReadToEnd();
                    sr.Close();
                }
                code = string.Format(template, data);

                // dont run empty
                if (code.Length > 0)
                {
                    // compile and execute
                    CompileAndExcute(code);
                }

                // all is good
                return true;
            }
            catch
            {
                // summit went wrong
                return false;
            }
        }

        private void CompileAndExcute(string code)
        {
            Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
            System.CodeDom.Compiler.CompilerParameters parameters = new System.CodeDom.Compiler.CompilerParameters { GenerateExecutable = false, GenerateInMemory = true };
            System.CodeDom.Compiler.CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);                                                

            if (results.Errors.Count > 0)
            {
                foreach (System.CodeDom.Compiler.CompilerError error in results.Errors)
                {
                    Console.Error.WriteLine("CONFIGURATION ERROR: Line number {0}, Error Number: {1}, '{2};\r\n\r\n", error.Line, error.ErrorNumber, error.ErrorText);
                }
            }
            else
            {
                var type = results.CompiledAssembly.GetType("Configurator");
                var method = type.GetMethod("main" );
                method.Invoke(null, new object[] { this.Director });
            }
        }

    
    }
}
